﻿namespace MicroCloud.AutoMapper
{
    /// <summary>
    /// 创建源类型与目标类型的配对
    /// </summary>
    public class MapFromAndMapToProfile : AutoMapperTupleBase
    {
        //字段
        private readonly ILogger<MapFromAndMapToProfile> _logger;
        
        /// <summary>
        /// 初始化一个 <see cref="MapFromAndMapToProfile"/> 类型的新实例
        /// </summary>
        /// <param name="loggerFactory">日志工厂接口</param>
        public MapFromAndMapToProfile(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<MapFromAndMapToProfile>();
        }

        /// <summary>
        /// 获取 顺序编号
        /// </summary>
        public override int OrderNo => -999999;

        /// <summary>
        /// 执行对象映射构建
        /// </summary>
        public override void CreateMap()
        {
            List<(Type Source, Type Target)> tuples = new();

            Type[] types = AssemblyManager.FindTypesByAttribute<MapFromAttribute>();
            foreach (Type targetType in types)
            {
                MapFromAttribute attribute = targetType.GetAttribute<MapFromAttribute>(true);
                foreach (Type sourceType in attribute.SourceTypes)
                {
                    var tuple = ValueTuple.Create(sourceType, targetType);
                    tuples.AddIfNotExist(tuple);
                }
            }

            types = AssemblyManager.FindTypesByAttribute<MapToAttribute>();
            foreach (Type sourceType in types)
            {
                MapToAttribute attribute = sourceType.GetAttribute<MapToAttribute>(true);
                foreach (Type targetType in attribute.TargetTypes)
                {
                    var tuple = ValueTuple.Create(sourceType, targetType);
                    tuples.AddIfNotExist(tuple);
                }
            }

            foreach ((Type Source, Type Target) in tuples)
            {
                CreateMap(Source, Target);
                _logger.LogDebug("构建 {Source} 到 {Target} 的对象映射关系", Source, Target);
            }
            _logger.LogInformation("构建共计 {count} 个对象映射关系", tuples.Count);
        }

    }
}